<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Ollama 智能助手</title>
    <style>
      body {
        font-family: Arial, sans-serif;
        background-color: #f0f4f8; /* 白天主题背景 */
        color: #333; /* 白天主题文字颜色 */
        margin: 0;
        padding: 0;
        display: flex;
        flex-direction: column;
        height: 100vh;
        transition: background-color 0.3s, color 0.3s; /* 过渡效果 */
      }
      h1 {
        color: #003366; /* 商务蓝 */
        text-align: center;
        padding: 8px;
        margin: 0;
        background-color: rgba(255, 255, 255, 0.6);
        border-bottom: 1px solid #ddd;
      }
      .chat-container {
        flex: 1;
        overflow-y: auto;
        padding: 20px;
        display: flex;
        flex-direction: column;
        gap: 15px;
      }
      .message {
        max-width: 70%;
        padding: 12px 16px;
        border-radius: 12px;
        word-wrap: break-word;
        position: relative;
      }
      .user-message {
        background-color: #007bff; /* 更亮的蓝色 */
        color: #fff;
        align-self: flex-end;
      }
      .bot-message {
        background-color: #fff;
        color: #333;
        border: 1px solid #ddd;
        align-self: flex-start;
        font-size: 15px;
        line-height: 1.6;
      }
      .user-message h1,
      .user-message h2,
      .user-message h3 {
        color: #fff;
        margin: 16px 0 8px 0;
      }
      .user-message p {
        margin: 8px 0;
      }
      .user-message ul,
      .user-message ol {
        margin: 8px 0;
        padding-left: 20px;
      }
      .user-message li {
        margin: 4px 0;
      }
      .user-message code {
        background-color: rgba(255, 255, 255, 0.1);
        padding: 2px 4px;
        border-radius: 3px;
        font-family: Consolas, monospace;
      }
      .user-message pre {
        background-color: rgba(255, 255, 255, 0.1);
        padding: 10px;
        border-radius: 6px;
        overflow-x: auto;
        margin: 10px 0;
      }
      .user-message pre code {
        background-color: transparent;
        padding: 0;
      }
      .bot-message h1 {
        font-size: 24px;
        color: #003366;
        margin: 16px 0 8px 0;
      }
      .bot-message h2 {
        font-size: 20px;
        color: #003366;
        margin: 14px 0 7px 0;
      }
      .bot-message h3 {
        font-size: 18px;
        color: #003366;
        margin: 12px 0 6px 0;
      }
      .bot-message p {
        margin: 8px 0;
      }
      .bot-message ul,
      .bot-message ol {
        margin: 8px 0;
        padding-left: 20px;
      }
      .bot-message li {
        margin: 4px 0;
      }
      .bot-message code {
        background-color: #f6f8fa;
        padding: 2px 4px;
        border-radius: 3px;
        font-family: Consolas, monospace;
      }
      .bot-message pre {
        background-color: #f6f8fa;
        padding: 10px;
        border-radius: 6px;
        overflow-x: auto;
        margin: 10px 0;
      }
      .bot-message pre code {
        background-color: transparent;
        padding: 0;
      }
      .bot-message blockquote {
        border-left: 4px solid #007bff;
        margin: 10px 0;
        padding: 8px 12px;
        background-color: #f8f9fa;
        color: #666;
      }
      .bot-message table {
        border-collapse: collapse;
        width: 100%;
        margin: 10px 0;
      }
      .bot-message th,
      .bot-message td {
        border: 1px solid #ddd;
        padding: 8px;
        text-align: left;
      }
      .bot-message th {
        background-color: #f6f8fa;
      }
      .bot-message a {
        color: #007bff;
        text-decoration: none;
      }
      .bot-message a:hover {
        text-decoration: underline;
      }
      .bot-message strong {
        color: #003366;
      }
      .bot-message em {
        color: #666;
      }
      .bot-message hr {
        border: none;
        border-top: 1px solid #ddd;
        margin: 16px 0;
      }
      .bot-message img {
        max-width: 100%;
        height: auto;
        border-radius: 4px;
        margin: 10px 0;
      }
      .message-time {
        font-size: 12px;
        color: #e0e0e0; /* 更亮的灰色，与深蓝色背景搭配 */
        margin-top: 4px;
        text-align: right;
      }
      .input-container {
        display: flex;
        gap: 10px;
        padding: 15px;
        background-color: #fff;
        border-top: 1px solid #ddd;
      }
      select {
        padding: 10px;
        border-radius: 8px;
        border: 1px solid #ccc;
        font-size: 16px;
        background-color: #fff;
        cursor: pointer;
      }
      textarea {
        flex: 1;
        padding: 10px;
        border-radius: 8px;
        border: 1px solid #ccc;
        font-size: 16px;
        resize: none;
      }
      button {
        background-color: #003366; /* 商务蓝 */
        color: #fff;
        padding: 10px 20px;
        border: none;
        border-radius: 8px;
        cursor: pointer;
        font-size: 16px;
      }
      button:hover {
        background-color: #002244; /* 深蓝 */
      }
      /* 夜间主题样式 */
      body.night-mode {
        background-color: #1e1e1e; /* 夜间主题背景 */
        color: #f0f0f0; /* 夜间主题文字颜色 */
      }
      .bot-message.night-mode {
        background-color: #2a2a2a; /* 夜间主题回复背景 */
        color: #f0f0f0; /* 夜间主题回复文字颜色 */
        border: 1px solid #444; /* 夜间主题边框颜色 */
      }
      .bot-message.night-mode strong {
        color: #e89939; /* 夜间模式下strong标签的颜色 */
      }
      .user-message.night-mode {
        background-color: #0056b3; /* 夜间主题用户消息背景 */
      }
      .message-time.night-mode {
        color: #888; /* 夜间主题时间颜色 */
      }
      .bot-message.night-mode code {
        background-color: #333; /* 更深的背景颜色 */
        color: #f8f8f2; /* 更亮的文字颜色 */
      }
      .bot-message.night-mode pre {
        background-color: #333; /* 更深的背景颜色 */
        color: #f8f8f2; /* 更亮的文字颜色 */
      }
      .bot-message.night-mode a {
        color: #4da6ff; /* 更亮的蓝色 */
      }
      .bot-message.night-mode a:hover {
        color: #80c1ff; /* 更亮的蓝色悬停效果 */
      }
    </style>
    <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
  </head>
  <body>
    <h1>Ollama</h1>
    <div class="chat-container" id="chat-container">
      <!-- 聊天记录将动态插入到这里 -->
    </div>
    <div class="input-container">
      <select id="model-select"></select>
      <textarea id="input" placeholder="输入你的问题..." rows="1"></textarea>
      <button id="submit-button">发送</button>
      <button id="theme-toggle">切换主题</button>
    </div>

    <script>
      // 获取输入框、选择框和提交按钮
      const input = document.getElementById("input");
      const modelSelect = document.getElementById("model-select");
      const submitButton = document.getElementById("submit-button");
      const themeToggle = document.getElementById("theme-toggle");

      // 存储对话历史
      let conversationHistory = [];

      // 为输入框添加键盘事件
      input.addEventListener("keydown", (e) => {
        if (e.key === "Enter" && !e.ctrlKey) {
          e.preventDefault(); // 阻止默认换行行为
          submitButton.click(); // 触发提交按钮点击事件
        } else if (e.key === "Enter" && e.ctrlKey) {
          // 按 Ctrl + Enter 时换行
          const start = input.selectionStart;
          const end = input.selectionEnd;
          input.value =
            input.value.substring(0, start) + "\n" + input.value.substring(end);
          input.selectionStart = input.selectionEnd = start + 1;
        }
      });

      // 获取当前时间，格式为 yyyy-mm-dd hh:mm:ss
      function getCurrentTime() {
        const now = new Date();
        const year = now.getFullYear();
        const month = String(now.getMonth() + 1).padStart(2, "0");
        const day = String(now.getDate()).padStart(2, "0");
        const hours = String(now.getHours()).padStart(2, "0");
        const minutes = String(now.getMinutes()).padStart(2, "0");
        const seconds = String(now.getSeconds()).padStart(2, "0");
        return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
      }

      // 提交按钮点击事件
      submitButton.addEventListener("click", async () => {
        const inputValue = input.value.trim();
        if (!inputValue) return; // 如果输入为空，则不处理

        const chatContainer = document.getElementById("chat-container");

        // 添加用户消息
        const userMessage = document.createElement("div");
        userMessage.className = "message user-message";
        userMessage.innerHTML = `
          ${inputValue}
          <div class="message-time">${getCurrentTime()}</div>
        `;
        chatContainer.appendChild(userMessage);

        // 清空输入框
        input.value = "";

        // 添加模型回复占位符
        const botMessage = document.createElement("div");
        botMessage.className = "message bot-message";
        botMessage.innerHTML = `
          处理中...
          <div class="message-time">${getCurrentTime()}</div>
        `;
        chatContainer.appendChild(botMessage);

        // 滚动到底部
        chatContainer.scrollTop = chatContainer.scrollHeight;

        try {
          conversationHistory.push({ role: "user", content: inputValue });
          console.log(conversationHistory);

          const response = await fetch("http://localhost:11434/api/chat", {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
            },
            body: JSON.stringify({
              model: modelSelect.value,
              messages: conversationHistory,
              stream: true, // 启用流式输出
            }),
          });

          const reader = response.body.getReader();
          const decoder = new TextDecoder();
          let result = "";

          while (true) {
            const { done, value } = await reader.read();
            if (done) break;

            const chunk = decoder.decode(value);
            const lines = chunk.split("\n");

            for (const line of lines) {
              if (line.trim() === "") continue;
              const data = JSON.parse(line);
              result += data.message.content;
              botMessage.innerHTML = `
                ${marked.parse(result)}
                <div class="message-time">${getCurrentTime()}</div>
              `;
            }

            // 滚动到底部
            chatContainer.scrollTop = chatContainer.scrollHeight;
          }

          conversationHistory.push({ role: "assistant", content: result });
        } catch (error) {
          console.error("Error:", error);
          botMessage.innerHTML = `
            调用 API 时出错: ${error.message}
            <div class="message-time">${getCurrentTime()}</div>
          `;
        }
      });

      // 主题切换功能
      themeToggle.addEventListener("click", () => {
        document.body.classList.toggle("night-mode");
        const botMessages = document.querySelectorAll(".bot-message");
        const userMessages = document.querySelectorAll(".user-message");

        botMessages.forEach((msg) => msg.classList.toggle("night-mode"));
        userMessages.forEach((msg) => msg.classList.toggle("night-mode"));
      });

      async function loadModelOptions() {
        try {
          const response = await fetch("http://localhost:11434/api/tags");
          const data = await response.json();
          const models = data.models;
          const modelSelect = document.getElementById("model-select");

          models.forEach((model) => {
            const name = model.name;
            const modelValue = model.model;
            const sizeGB = (model.size / 1024 ** 3).toFixed(1) + "G";
            const option = document.createElement("option");
            option.value = modelValue;
            option.textContent = `${name} - ${sizeGB}`;
            modelSelect.appendChild(option);
          });
        } catch (error) {
          console.error("Error loading model options:", error);
        }
      }

      // 在页面加载时调用函数
      window.addEventListener("load", loadModelOptions);
    </script>
  </body>
</html>
